#lang rosetta-racket


(provide loft-with-lines
         loft-with-surfaces
         loft-closed-with-lines
         loft-closed-with-surfaces
         loft-surface-with-lines
         loft-surface-with-surfaces
         loft-solid-with-lines
         loft-solid-with-surfaces
         
         ruled-loft-with-lines
         ruled-loft-with-surfaces
         ruled-loft-closed-with-lines
         ruled-loft-closed-with-surfaces
         ruled-loft-surface-with-lines
         ruled-loft-surface-with-surfaces
         ruled-loft-solid-with-lines
         ruled-loft-solid-with-surfaces)
 

(define (lines)
  (list
   (circle 5)
   (circle (xz 2 5) 3)
   (circle (xz -1 9) 4)))

(define (surfaces)
  (list
   (circle-surface 5)
   (circle-surface (xz 2 5) 3)
   (circle-surface (xz -1 9) 4)))

(define (closed-lines)
  (map
   (λ (segment)
     (move
      (segment-object segment)
      (rotate pi/2 (segment-normal segment) (circle 1))))
   (cut (par (circle 4)) 5)))

(define (closed-surfaces)
  (map
   (λ (segment)
     (move
      (segment-object segment)
      (rotate pi/2 (segment-normal segment) (circle-surface 1))))
   (cut (par (circle 4)) 5)))


(define (loft-with-lines)
  (lift
   (thunk (displayln "Loft with lines to create a surface"))
   (loft (lines))))

(define (loft-with-surfaces)
  (lift
   (thunk (displayln "Loft with surfaces to create a solid"))
   (loft (surfaces))))

(define (loft-closed-with-lines)
  (lift
   (thunk (displayln "Loft closed with lines to create a closed surface (solid)"))
   (loft-closed (closed-lines))))

(define (loft-closed-with-surfaces)
  (lift
   (thunk (displayln "Loft closed with surfaces to create a closed surface (solid)"))
   (loft-closed (closed-surfaces))))

(define (loft-surface-with-lines)
  (lift
   (thunk (displayln "Loft surface with lines to create a surface"))
   (loft-surface (lines))))

(define (loft-surface-with-surfaces)
  (lift
   (thunk (displayln "Loft surface with surfaces to create a surface"))
   (loft-surface (surfaces))))

(define (loft-solid-with-lines)
  (lift
   (thunk (displayln "Loft solid with lines to create a solid"))
   (loft-solid (lines))))

(define (loft-solid-with-surfaces)
  (lift
   (thunk (displayln "Loft solid with surfaces to create a solid"))
   (loft-solid (surfaces))))


(define (ruled-loft-with-lines)
  (lift
   (thunk (displayln "Ruled loft with lines to create a surface"))
   (ruled-loft (lines))))

(define (ruled-loft-with-surfaces)
  (lift
   (thunk (displayln "Ruled loft with surfaces to create a solid"))
   (ruled-loft (surfaces))))

(define (ruled-loft-closed-with-lines)
  (lift
   (thunk (displayln "Ruled loft closed with lines to create a closed surface (solid)"))
   (ruled-loft-closed (closed-lines))))

(define (ruled-loft-closed-with-surfaces)
  (lift
   (thunk (displayln "Ruled loft closed with surfaces to create a closed surface (solid)"))
   (ruled-loft-closed (closed-surfaces))))

(define (ruled-loft-surface-with-lines)
  (lift
   (thunk (displayln "Ruled loft surface with lines to create a surface"))
   (ruled-loft-surface (lines))))

(define (ruled-loft-surface-with-surfaces)
  (lift
   (thunk (displayln "Ruled loft surface with surfaces to create a surface"))
   (ruled-loft-surface (surfaces))))

(define (ruled-loft-solid-with-lines)
  (lift
   (thunk (displayln "Ruled loft solid with lines to create a solid"))
   (ruled-loft-solid (lines))))

(define (ruled-loft-solid-with-surfaces)
  (lift
   (thunk (displayln "Ruled loft solid with surfaces to create a solid"))
   (ruled-loft-solid (surfaces))))